package cz.acies.genea.ui.svg;

import java.util.Map;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class G2Rectangle extends G2Object
{
	private static final long serialVersionUID = 5373622861887996418L;
	
	public double x;
	public double y;
	public double width; 
	public double height;
	
	public G2Rectangle() {
		this(0, 0, 0, 0);
	}

	public G2Rectangle(G2Point p1, G2Point p2) {
		this(0, 0, 0, 0);
		computeShape(p1, p2);
	}

	public G2Rectangle(double x, double y, double width, double height) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	}

	// -----  -----------------------------------------------------------------

	protected void computeShape(G2Point p1, G2Point p2) {
		this.x = p1.x;
		if (p1.x > p2.x) {
			this.x = p2.x;
		}
		this.y = p1.y;
		if (p1.y > p2.y) {
			this.y = p2.y;
		}
		this.width = Math.abs(p2.x - p1.x);
		this.height = Math.abs(p2.y - p1.y);
	}

	// -----  -----------------------------------------------------------------
	
	@Override
	public String getType() {
		return "rect";
	}

	// -----  -----------------------------------------------------------------
	
	@Override
	public JsonObject toJSON(JsonObject element) {
		element = super.toJSON(element);
		JsonObject draw = (JsonObject) element.get("draw");
		draw.addProperty("x", x);
		draw.addProperty("y", y);
		draw.addProperty("width", width);
		draw.addProperty("height", height);
		
		return element;
	}
	
	// -----  -----------------------------------------------------------------
	
	public double getX() {
		return x;
	}

	public void setX(double x) {
		this.x = x;
	}

	public double getY() {
		return y;
	}

	public void setY(double y) {
		this.y = y;
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeith() {
		return height;
	}

	public void setHeith(double heith) {
		this.height = heith;
	}

	// -----  -----------------------------------------------------------------
	
	public String toString() {
		return "G2Rectangle[x = " + x + ", y = " + y + ", width = " + width + ", height = " + height + "]"; 
	}

	public void add (G2Rectangle rect) {
		double left = x < rect.x ? x : rect.x;
		double top = y < rect.y ? y : rect.y;
		double lhs = x + width;
		double rhs = rect.x + rect.width;
		double right = lhs > rhs ? lhs : rhs;
		lhs = y + height;
		rhs = rect.y + rect.height;
		double bottom = lhs > rhs ? lhs : rhs;
		x = left;  y = top;  width = right - left;  height = bottom - top;
	}

	public boolean contains (int x, int y) {
		return (x >= this.x) && (y >= this.y) && x < (this.x + width) && y < (this.y + height);
	}

	public boolean equals (Object object) {
		if (object == this) return true;
		if (!(object instanceof G2Rectangle)) return false;
		G2Rectangle r = (G2Rectangle)object;
		return (r.x == this.x) && (r.y == this.y) && (r.width == this.width) && (r.height == this.height);
	}

	public void intersect (G2Rectangle rect) {
		if (this == rect) return;
		double left = x > rect.x ? x : rect.x;
		double top = y > rect.y ? y : rect.y;
		double lhs = x + width;
		double rhs = rect.x + rect.width;
		double right = lhs < rhs ? lhs : rhs;
		lhs = y + height;
		rhs = rect.y + rect.height;
		double bottom = lhs < rhs ? lhs : rhs;
		x = right < left ? 0 : left;
		y = bottom < top ? 0 : top;
		width = right < left ? 0 : right - left;
		height = bottom < top ? 0 : bottom - top;
	}

	public G2Rectangle intersection (G2Rectangle rect) {
		if (this == rect) return new G2Rectangle (x, y, width, height);
		double left = x > rect.x ? x : rect.x;
		double top = y > rect.y ? y : rect.y;
		double lhs = x + width;
		double rhs = rect.x + rect.width;
		double right = lhs < rhs ? lhs : rhs;
		lhs = y + height;
		rhs = rect.y + rect.height;
		double bottom = lhs < rhs ? lhs : rhs;
		return new G2Rectangle (
			right < left ? 0 : left,
			bottom < top ? 0 : top,
			right < left ? 0 : right - left,
			bottom < top ? 0 : bottom - top);
	}

	public boolean intersects (int x, int y, int width, int height) {
		return (x < this.x + this.width) && (y < this.y + this.height) &&
			(x + width > this.x) && (y + height > this.y);
	}

	public boolean isEmpty () {
		return (width <= 0) || (height <= 0);
	}

	public G2Rectangle union (G2Rectangle rect) {
		double left = x < rect.x ? x : rect.x;
		double top = y < rect.y ? y : rect.y;
		double lhs = x + width;
		double rhs = rect.x + rect.width;
		double right = lhs > rhs ? lhs : rhs;
		lhs = y + height;
		rhs = rect.y + rect.height;
		double bottom = lhs > rhs ? lhs : rhs;
		return new G2Rectangle (left, top, right - left, bottom - top);
	}
}
